//#include "Engine.h"
//#include "App.h"
#include "Listener.h"
#include "Framework\Math\Vector.h"
//#include "Framework\Util\ProgrammerArt.h"
#include "micropather.h"


class MapNode{
	MapNode*	neighbors;
	int		neighborCount;
	vec3	centroid;
	int		terrainType;
};

typedef struct{
	void*		node;
	float		cost;
}StateCost;

class PlanetAI{
public:
	int		mapX;
	int		mapY;
	bool	doorsOpen;
	PlanetAI(){
		mapX=80;
		mapY=40;
		doorsOpen=true;
	}


	void NodeToXY( void* node, int* x, int* y ) 
	{
		int index = (int)node;
		*y = index / mapX;
		*x = index - *y * mapX;
	}

	void* XYToNode( int x, int y )
	{
		return (void*) ( y*mapX + x );
	}
	float computeDistanceOnSphere(vec3	cent,float radius,vec3	pa,vec3	pb){
		vec3 va=pa-cent;
		vec3 vb=pb-cent;
		//form orthonormal basis with first point..
		vec3 xaxis=normalize(va);
		vec3 yaxis=xaxis.zxy();
		yaxis.z*=-1.0f;
		vec3 zaxis=cross(normalize(yaxis),xaxis);
		yaxis=cross(xaxis,zaxis);
		float px=dot(pb,xaxis);
		float py=dot(pb,yaxis);
		float angDist=atan2(px,py);
		return abs(angDist*radius);
	}
	
	virtual float LeastCostEstimate( void* nodeStart, void* nodeEnd ) 
	{
		int xStart, yStart, xEnd, yEnd;
		NodeToXY( nodeStart, &xStart, &yStart );
		NodeToXY( nodeEnd, &xEnd, &yEnd );

		/* Compute the minimum path cost using distance measurement. It is possible
		   to compute the exact minimum path using the fact that you can move only 
		   on a straight line or on a diagonal, and this will yield a better result.
		*/
		int dx = xStart - xEnd;
		int dy = yStart - yEnd;
		return (float) sqrt( (double)(dx*dx) + (double)(dy*dy) );
	}
	bool Passable(int x,int	y){
		return true;
	}
	virtual void AdjacentCost( void* node, std::vector< StateCost > *neighbors ) 
	{
		int x, y;
		const int dx[8] = { 1, 1, 0, -1, -1, -1, 0, 1 };
		const int dy[8] = { 0, 1, 1, 1, 0, -1, -1, -1 };
		const float cost[8] = { 1.0f, 1.41f, 1.0f, 1.41f, 1.0f, 1.41f, 1.0f, 1.41f };

		NodeToXY( node, &x, &y );

		for( int i=0; i<8; ++i ) {
			int nx = x + dx[i];
			int ny = y + dy[i];

			int pass = Passable( nx, ny );
			if ( pass > 0 ) {
				if ( pass == 1 || doorsOpen ) 
				{
					// Normal floor
					StateCost nodeCost = { XYToNode( nx, ny ), cost[i] };
					neighbors->push_back( nodeCost );
				}
				else 
				{
					// Normal floor
					StateCost nodeCost = { XYToNode( nx, ny ), FLT_MAX };
					neighbors->push_back( nodeCost );
				}
			}
		}
	}

	virtual void PrintStateInfo( void* node ) 
	{
		int x, y;
		NodeToXY( node, &x, &y );
		printf( "(%d,%d)", x, y );
	}

};
